#ifndef __BS_APP_COM_H__
#define __BS_APP_COM_H__

#include <stdint.h>
#include "bs_app.h"
#include "bs_ring_buf.h"

#define DATA_PACKET_MAX_LEN    1024

typedef enum E_Command_type {
    CMD_OK = 0,
    CMD_FIND_DEVICE,
    CMD_FIND_DEVICE_RESP,
    CMD_FIND_SLAVE,
    CMD_FIND_SLAVE_RESP,
    CMD_QUERY_STATE,
    CMD_QUERY_STATEResp,

    CMD_ADD_IMAGE_START,     
    CMD_ADD_IMAGE_START_RESP, 
    CMD_ADD_IMAGE_END,       
    CMD_ADD_IMAGE_END_RESP,   

    CMD_CHIP_ERASE,
    CMD_SECTOR_ERASE,
    CMD_CHIP_PROGRAM,       
    CMD_CHIP_READ,          
    CMD_CHIP_OFFLINE_AUTO,   
    CMD_CHIP_OFFLINE_AUTO_RESP,

    CMD_GET_LOG,
    CMD_CLOSE_LOG,

    CMD_SEND_DATA_PACKET,    
    CMD_GET_DATA_PACKET,     
    CMD_GET_DATA_PACKET_RESP,

    CMD_ERROR = 0x0FFFF,
} E_Command_type;


typedef enum{
	RECV_STA_IDLE = 0,
    RECV_STA_WAIT_FRAME,

    RECV_STA_WAIT_DATA,
    RECV_STA_CRC_ERROR,
    RECV_STA_DATA_OK,
    RECV_STA_ERROR = 0xFF,
}recv_sta_t;


typedef enum{
	NO_ERROR,
    ERROR_FRAME_LEN,
    ERROR_FRAME_CRC16,
    ERROR_FRAME_CMD_ILLEGAL,
    ERROR_FRAME_PARSE_ILLEGAL,
    ERROR_DEVICE_NOT_FOUND,
    ERROR_DEVICE_BUSY,
    ERROR_DEVICE_DAMAGED,
    ERROR_DEVICE_PAIR_FAILED,
    ERROR_DEVICE_NOT_SPACE,
    ERROR_INCORRECT_IMAGE_KEY,
    ERROR_IMAGE_DAMAGED,
    ERROR_IMAGE_NO_EXISTS,
    ERROR_IMAGE_VERIFY_FAILED,
    ERROR_inter_flash_ERASE_FAILED,
    ERROR_exter_flash_ERASE_FAILED,
    ERROR_DEVICE_NO_IMAGES,
    ERROR_ILLEGAL_IMAGE_INDEX,
    ERROR_INT_IMAGE_DAMAGED,
    ERROR_EXT_IMAGE_DAMAGED,
    ERROR_DETECT_CHIP_FAILED,
    ERROR_CHIP_MISMATCH,
    ERROR_UNRECOGNIZED_CHIP,
    ERROR_CHIP_IS_OFFLINE,
    ERROR_GET_CHIP_SYS_INFO_FAILED,
    ERROR_CHIP_READ_FAILED,
    ERROR_CHIP_MASS_ERASE_FAILED,
    ERROR_CHIP_SECTOR_ERASE_FAILED,
    ERROR_CHIP_PROG_TIMES_EXHAUSTED,
    ERROR_CHIP_PROGRM_FAILED,
    ERROR_ILLEGAL_ADDR,
    ERROR_ILLEGAL_LEN,
    ERROR_CHIP_CHECK_BLANK_FAILED,
    ERROR_CHIP_NO_CODE,
    ERROR_CHIP_CHECK_FREQ_FAILED,
    ERROR_CHIP_CHECK_NOLOAD_CUR_FAILED,
    ERROR_CHIP_CHECK_STANDBY_FAILED,
    ERROR_SD_CARD_NO_DETECTED,
    ERROR_SD_CARD_DAMAGED,
    ERROR_SPI_FLASH_NO_DETECTED,
    ERROR_SPI_FLASH_DAMAGED,
    ERROR_LCD_NO_DETECTED,
    ERROR_LCD_DAMAGED,
    ERROR_WIFI_BLE_NO_DETECTED,
    ERROR_WIFI_BLE_DAMAGED,
    ERROR_NFC_NO_DETECTED,
    ERROR_NFC_DAMAGED,
    ERROR_USB_DAMAGED,
    ERROR_BTN_DAMAGED,
    ERROR_LED_DAMAGED,
    ERROR_RTC_LOW_BATTERY,
    ERROR_RTC_BATTERY_DAMAGED,
    ERROR_POWER_LOW_VOL,
    ERROR_POWER_SHORT,
    ERROR_WRITER_INTERFACE_SHORT,
    ERROR_EXT_POW_INPUT,
    ERROR_ILLEGAL_DEVICE_CFG,
    ERROR_ILLEGAL_COUNT_PROG_TIMES,
    ERROR_LATEST_VER,
    ERROR_DATA_LEN_EXCEED_LIMIT,
    ERROR_ILLEGAL_DATA_TOTAL_LEN,
    ERROR_ILLEGAL_DATA_TOTAL_CRC32,

}E_Comm_error_t;


#pragma pack(push,1)
typedef struct S_Cmd_package {
    uint16_t        frame_num;    // 帧序号,每次加1
    uint8_t         format_ver;   // 通讯协议版本
    uint32_t        key_group;    // 密钥的生成
    uint16_t        random;       // 随机数
    uint16_t        cmd;          // 通讯命令
    uint16_t        data_len;     // 有效数据长度
    // uint8_t         *data_packet; // 有效数据长度
    // uint16_t        crc16;
    // uint16_t        tail[6];      // 帧尾   
} S_Cmd_package_t;

#pragma pack(pop)

typedef enum {
    COMM_IDLE,
    COMM_WAIT_CMD,
    COMM_DISPATCH_CMD,
    COMM_CRC_ERROR,
    COMM_ERROR,
} bs_comm_state_t;


typedef struct S_Writer {
    bs_comm_state_t   state;
    E_Command_type    m_Cmd;
    circ_buf_t        m_circ_buffer;
    uint8_t           data_packet[1024+128];
    uint16_t          crc16;
    uint8_t           tail[6];
    uint16_t          ack_nbr;

    uint32_t          fw_len;          // 固件长度
    uint16_t          last_error;
}S_Writer_t;

#pragma pack(push,1)
typedef struct S_Cmd_FindDevice {
    uint8_t           file_name[9];
}S_Cmd_FindDevice_t;

typedef struct S_Cmd_ImageStart {
    uint8_t           file_name[128 + 1];
    uint8_t           download_key[16];
    uint32_t          encrypted_file_len;
    uint32_t          encrypted_file_crc32;
}S_Cmd_ImageStart_t;


typedef struct S_Cmd_SendDataPacket {
    uint16_t          data_len;
    uint8_t           data_array[DATA_PACKET_MAX_LEN];
}S_Cmd_SendDataPacket_t;

typedef struct S_Cmd_AddImageEnd {
    uint8_t           file_name[128 + 1];
}S_Cmd_AddImageEnd_t;


typedef struct S_Cmd_ChipProgram {
    uint32_t          address;
    uint32_t          len;
}S_Cmd_ChipProgram_t;


typedef struct S_Cmd_GetLog {
    uint32_t           address;
    uint32_t           len;
}S_Cmd_GetLog_t;


typedef union U_pkg_func {
    S_Cmd_FindDevice_t         m_find_device;
    S_Cmd_ImageStart_t         m_image_start;
    S_Cmd_SendDataPacket_t     m_send_packet;
    S_Cmd_AddImageEnd_t        m_add_image_end;
    S_Cmd_ChipProgram_t        m_chip_pg;
    S_Cmd_GetLog_t             m_fetch_log;
} U_pkg_func_t;


#pragma pack(pop)

// 响应
void bs_comm_init(void);
void bs_comm_reset(void);
void bs_comm_process(void);
int bs_comm_response(E_Command_type cmd, void *data_pkg, uint32_t size);


#endif

